package de.kardass.jsmatep.in;

import java.util.List;

import de.kardass.jsmatep.in.config.ParserConfiguration;
import de.kardass.jsmatep.in.config.ParserConfigurationFactory;
import de.kardass.jsmatep.in.config.field.Field;
import de.kardass.jsmatep.in.reader.RecordReader;
import de.kardass.jsmatep.in.reader.RecordReaderFactory;

public class DynamicValueObjectFactory {

    /** The import configuration used by this parser */
    private final ParserConfiguration parserConfiguration;

    /** The record reader used by this mapper depending on a given configuration */
    private final RecordReader recordReader;

    /**
     * @param parserConfiguration
     */
    public DynamicValueObjectFactory(ParserConfiguration parserConfiguration) {
        this.parserConfiguration = parserConfiguration;
        this.recordReader = RecordReaderFactory.getRecordReader(parserConfiguration);
    }
    
    public DynamicValueObjectFactory(String configFileName) {
        this(ParserConfigurationFactory.createConfiguration(configFileName));
    }

    /**
     * Returns a given data string as a {@linkplain DynamicValueObject} representation
     * based on a given configuration, 
     * @param parserConfiguration
     * @param record
     * @return
     * @author Manfred Kardass
     * @since 10.05.2010
     */
    public DynamicValueObject asDynamicValueObject(String record) {
        if (ImportProcessor.skipContent(parserConfiguration, record)) {
            // do nothing
            return null;
        }
        final DynamicValueObject result = new DynamicValueObject();
        final List<Field<?>> fields = parserConfiguration.getFields();
        String aValueString;
        for (Field<?> aField : fields) {
            aValueString = recordReader.readField(aField, record);
            result.put(aField.getName(), aValueString);
            try {
                // try to parse string into target type
                aField.getAsTypedValue(aValueString);
                // everything's ok, just for checking type
            } catch (Exception e) {
                // set error message in dynamic value object for later use
                result.setMessage(e.getMessage());
            }
        }
        return result;
    }

    /** 
     * Returns the factory's parser configuration.
     * @return 
     *      the factory's parser configuration
     */
    public ParserConfiguration getParserConfiguration() {
        return parserConfiguration;
    }

}
